<?php

/**
 * Description of Core_Request
 * @package Core
 * @author superx
 */
class Core_Request extends Core_Singleton {

    protected $_cmd;
    protected $_identifier;
    protected $_params = array();
    protected $_httpHeaders = array();
    protected $_userAgent;
    protected $_lang = 'zh';
    protected $_files = array();

    /**
     *
     * @return Core_Request
     */
    public static function getInstance() {
        return parent::getInstance();
    }

    protected function __construct() {
        if (isset($_SERVER['REQUEST_URI'])) {
            $cmd = $_SERVER['REQUEST_URI'];
            if ($pos = strpos($cmd, '?')) {
                $cmd = substr($cmd, 0, $pos);
            }
            $this->_cmd = trim($cmd, '/');
        }

        $this->_params = $_REQUEST;

        $this->_parseLang();
        $this->_parseHttpHeaders();
        $this->_fixFiles();

    }

    public function getParams() {
        return $this->_params;
    }

    public function getParam($key, $default = null) {
        if ($this->hasParam($key)) {
            return $this->_params[$key];
        } else {
            return $default;
        }
    }

    public function setParam($key, $value) {
        $this->_params[$key] = $value;
    }

    public function setParams(array $params) {
        $this->_params = $params;
    }

    public function addParams(array $params) {
        $this->_params = array_merge($this->_params, $params);
    }

    public function hasParam($key) {
        return isset($this->_params[$key]);
    }

    public function getCmd() {
        return $this->_cmd;
    }

    public function setCmd($cmd) {
        $this->_cmd = $cmd;
    }

    public function getIdentifier() {
        return $this->_identifier;
    }

    protected function _parseLang() {
        $lang = strtolower($this->getParam('lang', 'zh'));
        $supported_langs = Core_Config::get('Core.Lang', []);

        $supported = false;
        foreach ($supported_langs as $lang_internal => $lang_arr) {
            if (in_array($lang, $lang_arr)) {
                $lang = $lang_internal;
                $supported = true;
                break;
            }
        }
        $this->_lang = ($supported) ? $lang : 'zh';
    }

    protected function _parseHttpHeaders() {
        $items = array(
            'REMOTE_ADDR',
            'REQUEST_TIME',
            'HTTP_USER_AGENT',
            'REQUEST_METHOD',
            'HTTP_REFERER',
            'CONTENT_TYPE',
        );
        $ori_headers = array_merge($_SERVER, $_ENV);
        $parsed_headers = array();
        foreach ($items as $key) {
            $convert_key = strtr(strtolower($key), array('http_' => '', '_' => '-'));
            if (!empty($ori_headers[$key])) {
                $parsed_headers[$convert_key] = $ori_headers[$key];
            }
        }

        $this->_httpHeaders = $parsed_headers;
    }

    public function getHttpHeaders() {
        return $this->_httpHeaders;
    }

    public function getHttpHeader($item) {
        return isset($this->_httpHeaders[$item]) ? $this->_httpHeaders[$item] : null;
    }

    public function isMultipart() {
        return $this->isPost() && (strpos($this->getHttpHeader('content-type'), 'multipart/form-data') !== false);
    }

    protected function _fixFiles() {
        if (!$this->isMultipart()) {
            return;
        }
        if (isset($_FILES) && is_array($_FILES)) {
            $this->_files = $_FILES;
        } else {
            $this->_files = array();
        }
    }

    public function isMethod($method) {
        return strtoupper($method) == strtoupper($this->getHttpHeader('request-method'));
    }

    public function isPost() {
        return $this->isMethod('POST');
    }

    public function getFiles() {
        return $this->_files;
    }

    public function setFiles(array $files) {
        $this->_files = $files;
    }

    public function getLang() {
        return $this->_lang;
    }

}

